#include <LitStdAfx.h>
#include <LitResourcesList.h>

namespace Lit
{
	ResourcesList::ResourcesList( )
		: mLocations( ),
		mMaterials( ),
		mMeshes( ),
		mTextures( ),
		mParticles( ),
		mCompositors( )
	{
		mResourceFoundCallback = boost::bind( &ResourcesList::_dummy_resourceFoundCallback, this, _1 );
	}
	ResourcesList::ResourcesList( const ResourcesList& rk ){
		mLocations=rk.mLocations;
		mMaterials=rk.mMaterials;
		mMeshes=rk.mMeshes;
		mTextures=rk.mTextures;
		mParticles=rk.mParticles;
		if( mResourceFoundCallback ) mResourceFoundCallback=rk.mResourceFoundCallback;
		mCompositors=rk.mCompositors;
	}
	ResourcesList::~ResourcesList()
	{
	}
	ResourcesList& ResourcesList::operator=( const ResourcesList& rk ){
		mLocations=rk.mLocations;
		mMaterials=rk.mMaterials;
		mMeshes=rk.mMeshes;
		mTextures=rk.mTextures;
		mParticles=rk.mParticles;
		if( mResourceFoundCallback ) mResourceFoundCallback=rk.mResourceFoundCallback;
		mCompositors=rk.mCompositors;
		return *this;
	}
		

	void ResourcesList::_dummy_resourceFoundCallback( const ResourceDescription& ){}

	void ResourcesList::setResourceFoundCallback( ResourceFoundCallback cbk ){ mResourceFoundCallback = cbk; }
	ResourcesList::ResourceFoundCallback& ResourcesList::resourceFoundCallback(){ return mResourceFoundCallback; }

	void ResourcesList::updateLocationList(){
		mLocations.clear();
		// List Resource Locations
		Ogre::StringVector groups(Ogre::ResourceGroupManager::getSingleton().getResourceGroups());
		for( auto g = groups.begin(); g!=groups.end(); g++ )
		{
			Ogre::ResourceGroupManager::LocationList lst = Ogre::ResourceGroupManager::getSingleton().getResourceLocationList(*g);
			for( auto i=lst.begin(); i!=lst.end(); i++ )
				mLocations.push_back( ResourceLocation((*i)->archive->getName(), (*i)->archive->getType(), *g) );
		}
	}
	void ResourcesList::updateMaterialList(){
		// Display Resources
		// Materials
		mMaterials.clear();
		Ogre::MaterialManager::ResourceMapIterator itc=Ogre::MaterialManager::getSingleton().getResourceIterator();
		while( itc.hasMoreElements() )
		{
			Ogre::MaterialPtr m = itc.getNext();
			mMaterials.push_back( ResourceDescription(m->getName(), "Material", Ogre::PixelBox()) );
			mResourceFoundCallback( mMaterials.back() );
		}
	}
	void ResourcesList::updateMeshList(){
		// Display Resources
		// Models
		mMeshes.clear();
		Ogre::StringVectorPtr vec(Ogre::ResourceGroupManager::getSingleton().findResourceNames( Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, "*.mesh" ));
		std::map<std::string, bool> map;
		for( auto i = vec->begin(); i!=vec->end(); i++ )
		{
			mMeshes.push_back( ResourceDescription((*i), "Mesh", Ogre::PixelBox()) );
			map[(*i)] = true;
			mResourceFoundCallback( mMeshes.back() );
		}
		auto it = Ogre::MeshManager::getSingleton().getResourceIterator();
		while( it.hasMoreElements() )
		{
			std::string name = it.getNext()->getName();
			if( map.find(name) == map.end() )
			{
				mMeshes.push_back( ResourceDescription(name, "Mesh", Ogre::PixelBox()) );
			}
		}
	}
	void ResourcesList::updateCompositorList(){
		// Display Resources
		// Compositors
		mCompositors.clear();
		Ogre::CompositorManager::ResourceMapIterator it = Ogre::CompositorManager::getSingleton().getResourceIterator();
		while( it.hasMoreElements() )
		{
			Ogre::CompositorPtr p = it.getNext();
			mCompositors.push_back( ResourceDescription(p->getName(), "Compositor", Ogre::PixelBox()) );
			mResourceFoundCallback( mCompositors.back() );
		}
	}
	void ResourcesList::updateTextureList(){
		// Display Resources
		// Textures
		Ogre::TextureManager::ResourceMapIterator ita=Ogre::TextureManager::getSingleton().getResourceIterator();
		mTextures.clear();
		while( ita.hasMoreElements() )
		{
			Ogre::TexturePtr tex = ita.getNext();
			mTextures.push_back( ResourceDescription(tex->getName(), "Texture", Ogre::PixelBox()) );
			mResourceFoundCallback( mTextures.back() );
		}
	}
	void ResourcesList::updateLists( )
	{
		updateLocationList();
		updateMaterialList();
		updateMeshList();
		updateTextureList();
		updateCompositorList();
	}
		
	const ResourcesList::LocationList& ResourcesList::locations() const{ return mLocations; }
	
	const ResourcesList::List& ResourcesList::compositors() const{ return mCompositors; }
	const ResourcesList::List& ResourcesList::materials() const{ return mMaterials; }
	const ResourcesList::List& ResourcesList::meshes() const{ return mMeshes; }
	const ResourcesList::List& ResourcesList::textures() const{ return mTextures; }
};